package org.the.gsdo.client;

import java.util.Map;

import org.the.gsdo.shared.SendTextToServerResult;

import com.google.gwt.activity.shared.AbstractActivity;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.place.shared.Place;
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.place.shared.PlaceTokenizer;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Label;

public class ResponsePanel extends BasePanel {

	private Label textToServerLabel;
	private HTML serverResponseLabel;

	public ResponsePanel() {
		HTMLPanel panel = new HTMLPanel(GsdoResources.INSTANCE.responseHtml().getText());
		initWidget(panel);
		textToServerLabel = new Label();
		panel.add(textToServerLabel, "textToServerLabel");
		serverResponseLabel = new HTML();
		panel.add(serverResponseLabel, "serverResponseLabel");
		final Button closeButton = new Button("Close");
		panel.add(closeButton, "closeButton");
		//
		closeButton.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				placeController.goTo(new InputPanel.InputPlace());
			}
		});
	}

	@Override
	public void nextPlace(Place place) {
		ResponsePlace responsePlace = (ResponsePlace)place;
		if (responsePlace.isError()) {
			textToServerLabel.setText("");
			serverResponseLabel.addStyleName("serverResponseLabelError");
			serverResponseLabel.setHTML(responsePlace.getErrorText());
		} else {
			serverResponseLabel.removeStyleName("serverResponseLabelError");
			textToServerLabel.setText(responsePlace.getResult().getToServer());
			serverResponseLabel.setHTML(responsePlace.getResult().getResponse());
		}
	}

	@Override
	public void onShow() {
		// nothing todo
	}

	public static class ResponseActivity extends AbstractActivity {

		private ResponsePanel responsePanel;

		@Override
		public void start(AcceptsOneWidget panel, EventBus eventBus) {
			panel.setWidget(getView());
		}

		public IsPlaceWidget getView() {
			if (responsePanel == null) {
				responsePanel = new ResponsePanel();
			}
			return responsePanel;
		}

		public ResponseActivity nextPlace(Place place) {
			getView().nextPlace(place);
			return this;
		}

		public ResponseActivity with(PlaceController placeController) {
			getView().withController(placeController);
			return this;
		}

	}

	public static class ResponsePlace extends Place {

		private boolean error;
		private String errorText;
		private SendTextToServerResult result;

		public ResponsePlace(String text) {
			this.error = true;
			this.errorText = text;
		}

		public SendTextToServerResult getResult() {
			return this.result;
		}

		public String getErrorText() {
			return this.errorText;
		}

		public boolean isError() {
			return this.error;
		}

		public ResponsePlace(SendTextToServerResult result) {
			this.result = result;
		}

		public String getName() {
			return "response&" + (result != null ? ("id=" + result.getUuid()) : "error");
		}

		@Override
		public String toString() {
			return (result != null ? result.getResponse() : "error: " + errorText);
		}

		public static class Tokenizer implements PlaceTokenizer<ResponsePlace> {

			private static Map<String,SendTextToServerResult> map = new java.util.HashMap<String, SendTextToServerResult>();

			@Override
			public ResponsePlace getPlace(String token) {
				if (token.endsWith("error")) {
					return new ResponsePlace(SERVER_ERROR);
				} else {
					SendTextToServerResult result = map.get(TokenizerUtil.get(token, "id"));
					return new ResponsePlace(result);
				}
			}

			@Override
			public String getToken(ResponsePlace place) {
				if (place.getResult() != null) {
					// local cache
					// we could cache it on the server
					map.put(place.getResult().getUuid(), place.getResult());
				}
				return place.getName();
			}

		}
	}

}
